package handlers

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"

	"filehive-backend/config"
	"filehive-backend/utils"
)

// UploadHandler 上传处理器
type UploadHandler struct {
	config config.Config
}

// NewUploadHandler 创建上传处理器
func NewUploadHandler(cfg config.Config) *UploadHandler {
	return &UploadHandler{config: cfg}
}

// UploadFiles 上传文件
func (h *UploadHandler) UploadFiles(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		utils.RespondError(w, http.StatusMethodNotAllowed, "方法不允许")
		return
	}

	// 限制请求大小
	r.Body = http.MaxBytesReader(w, r.Body, h.config.Storage.MaxFileSize)

	// 解析多部分表单
	err := r.ParseMultipartForm(h.config.Storage.MaxMemory)
	if err != nil {
		utils.RespondError(w, http.StatusBadRequest, "解析上传表单失败")
		return
	}

	pathParam := r.URL.Query().Get("path")
	
	uploadPath, safe := utils.SafePath(h.config.Storage.Path, pathParam)
	if !safe {
		utils.RespondError(w, http.StatusBadRequest, "无效的路径")
		return
	}

	// 确保上传目录存在
	err = utils.EnsureDir(uploadPath)
	if err != nil {
		utils.RespondError(w, http.StatusInternalServerError, "创建上传目录失败")
		return
	}

	files := r.MultipartForm.File["files"]
	if len(files) == 0 {
		utils.RespondError(w, http.StatusBadRequest, "没有文件上传")
		return
	}

	uploadedFiles := make([]string, 0)

	for _, fileHeader := range files {
		// 打开上传的文件
		src, err := fileHeader.Open()
		if err != nil {
			continue
		}
		defer src.Close()

		// 清理文件名，防止路径遍历攻击
		safeFilename := utils.SanitizeFilename(fileHeader.Filename)

		// 创建目标文件
		dstPath := filepath.Join(uploadPath, safeFilename)
		dst, err := os.Create(dstPath)
		if err != nil {
			continue
		}
		defer dst.Close()

		// 复制文件内容
		_, err = io.Copy(dst, src)
		if err != nil {
			os.Remove(dstPath) // 清理失败的文件
			continue
		}

		uploadedFiles = append(uploadedFiles, safeFilename)
	}

	if len(uploadedFiles) == 0 {
		utils.RespondError(w, http.StatusInternalServerError, "所有文件上传失败")
		return
	}

	utils.RespondSuccess(w, fmt.Sprintf("成功上传 %d 个文件", len(uploadedFiles)), map[string]interface{}{
		"uploadedFiles": uploadedFiles,
		"count":         len(uploadedFiles),
	})
} 